#![cfg_attr(feature = "axstd", no_std)]
#![cfg_attr(feature = "axstd", no_main)]

#[cfg(feature = "axstd")]
extern crate axstd as std;

#[cfg(feature = "axstd")]
use std::{string::String, vec::Vec};

use gpio_cmd::{self, Response as GpioResponse};

#[cfg_attr(feature = "axstd", unsafe(no_mangle))]
fn main() {
    #[cfg(feature = "axstd")]
    {
        let mut args = std::env::args();
        let _program = args.next();
        let Some(subcmd) = args.next() else {
            print_usage();
            return;
        };

        let params: Vec<String> = args.collect();

        match gpio_cmd::parse_command(&subcmd, params.iter().map(|s| s.as_str())) {
            Ok(command) => match gpio_cmd::execute(command) {
                GpioResponse::Set { bank, pin, level } => {
                    println!(
                        "gpio: bank {bank} pin {pin} set to {}",
                        gpio_cmd::display_level(level)
                    );
                }
                GpioResponse::Get { bank, pin, level } => {
                    println!(
                        "gpio: bank {bank} pin {pin} is {}",
                        gpio_cmd::display_level(level)
                    );
                }
                GpioResponse::Toggle { bank, pin } => {
                    println!("gpio: bank {bank} pin {pin} toggled");
                }
                GpioResponse::Help => print_usage(),
            },
            Err(err) => {
                println!("gpio: {}", err);
                print_usage();
            }
        }
    }

    #[cfg(not(feature = "axstd"))]
    {
        panic!("gpio-tool requires the `axstd` feature to run");
    }
}

#[cfg(feature = "axstd")]
fn print_usage() {
    println!("GPIO Tool");
    for line in gpio_cmd::USAGE_LINES {
        println!("{line}");
    }
}
